﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// NotReviewedButNeeded

#pragma once

#include "GcmpUiViewInterface.h"
#include "GcmpApiDeclaration.h"
#include "WeakReferenceable.h"
#include "ElementId.h"

namespace gcmp
{
    class IModelView;
    class IGraphicsElementShape;
    class IUiDocument;
    class ICanvas;
    class ICamera;
    class IUiViewEvent;
    class IViewerContext;
    class Vector3d;
    class IUiViewMouseEvent;
    class IUiViewContextMenuEvent;
    class Vector2i;
    class IGcmpUserDrag;

    /// \brief 光标类型
    enum class CursorType : int32_t
    {
        ArrowCursor = 0,            ///< 默认箭头
        CrossHairCursor,            ///< 十字光标(带准心)
        CrossCursor,                ///< 十字光标
        DrawLineCursor,             ///< 画线
        DrawArcCursor,              ///< 画圆弧
        DrawArcTangentCursor,       ///< 画圆弧切线
        DrawArcFilletCursor,        ///< 画圆弧圆角
        DrawCircleCursor,           ///< 画圆形
        DrawRectCursor,             ///< 画矩形
        DrawEllipseCursor,          ///< 画椭圆
        DrawPolygonCursor,          ///< 画多边形
        DrawExternalPolygonCursor,  ///< 画外接多边形
        DrawAxisCursor,             ///< 画轴线
        AlignCursor,                ///< 对齐
        TrimAngleCursor,            ///< 修角
        Trim1Cursor,                ///< 裁剪
        TrimMultiCursor,            ///< 多裁剪
        DrawByPick,                 ///< 拾取线
        DrawEllipseArcCursor,       ///< 画椭圆弧
        ArrowCursorWithMinus,       ///<带负号的箭头
        ArrowCursorWithPlus,        ///<带正号的箭头
        ArrowCursorWithBan,         ///<带禁令的箭头
        NotAllowed,                 ///< 禁用
        Custom                      ///<自定义
    };
   
    /// \brief Ui视图
    FINAL_INTERFACE class GCMP_UI_VIEW_INTERFACE_EXPORT IUiView:public WeakReferenceable
    {
        DEFINE_CAST_BASE(gcmp::IUiView)

    public:

        /// \brief 析构函数
        virtual ~IUiView();

        /// \brief 获取视图的Parent视图
        ///
        /// \return Parent视图
        virtual IUiView * Parent() = 0;
        virtual const IUiView * Parent() const = 0;

        /// \brief 获取Ui视图的id
        ///
        /// \return Ui视图的id
        virtual int GetId() const = 0;

        /// \brief 获取Ui视图的标识符
        ///
        /// \return Ui视图的标识符
        virtual std::wstring GetTag() const = 0;

        /// \brief 获取画布
        ///
        /// \return 画布指针
        virtual const ICanvas* GetCanvas() const = 0;
        virtual ICanvas* GetCanvas() = 0;

        /// \brief 获取Ui文档
        ///
        /// \return Ui文档指针
        virtual const IUiDocument* GetUiDocument() const = 0;
        virtual IUiDocument* GetUiDocument() = 0;

        /// \brief 获取模型视图id
        ///
        /// \return 模型视图的id
        virtual ElementId GetModelViewId() const = 0;

        /// \brief 获取模型视图
        ///
        /// \return 模型视图指针
        virtual IModelView* GetModelView() const = 0;

        /// \brief 获取是否为子视图
        ///
        /// \return true，是子视图；false，不是子视图
        virtual bool IsSubUiView() const = 0;

        /// \brief 获取子模型视图id,如果不是子视图则为空
        ///
        /// \return 模型视图的id
        virtual ElementId GetSubModelViewId() const = 0;
        /// \brief 标记视图是否需要重建
        ///
        /// \param needRebuild 视图是否需要重建
        GCMP_OBSOLETE_API(2021/04/01, ICanvas::MarkNeedRebuild(bool needRebuild))
            virtual void MarkNeedRebuild(bool needRebuild) = 0;

        /// \brief 更新该Ui视图
        ///
        /// 仅监控Elements增，删和改增量刷新视图（默认调用）
        GCMP_OBSOLETE_API(2021/04/01, ICanvas::Refresh())
            virtual void Refresh() = 0;

        /// \brief 更新该Ui视图
        ///
        /// 可见性条件发生变化时调用（包括监控Elements增，删和改增量刷新视图，性能比Refresh差点）
        GCMP_OBSOLETE_API(2021/04/01, ICanvas::RefreshByVisibilityConditionChanged())
            virtual void RefreshByVisibilityConditionChanged() = 0;

        /// \brief 获取默认action
        ///
        /// \return 返回默认工具（当所有Action退出之后启动的工具）
        virtual const std::wstring& GetDefaultActionCommand() = 0;

        /// \brief 设置默认action的命令id
        ///
        /// 设置之后会替换平台默认的action
        /// \return true表示成功， false表示失败
        virtual bool SetDefaultActionCommand(const std::wstring& defaultActionCommand) = 0;

        /// \brief 获取视图内当前所有可见Grep
        ///
        /// \return 所有可见图形表达图形节点指针
        virtual std::vector<const IGraphicsElementShape*> GetVisibleGreps() = 0; //GetVisibleElementShapes

        /// \brief 获取所有在视图范围内可见可编辑的Grep
        /// 
        /// 该接口中会调用IModelView::GetEditableModelViewElementShapes()，图纸视图中有激活视口时，会对所得editableGreps进行过滤 
        /// \return 所有可编辑图形表达图形节点指针
        virtual std::vector<const IGraphicsElementShape*> GetEditableGreps() = 0;

        /// \brief 设置光标
        ///
        /// \param cursorPath 光标图片路径
        virtual void SetCursorPath(const std::wstring &cursorPath) = 0;

        /// \brief 获取光标
        ///
        /// \return 光标图片路径
        virtual const std::wstring& GetCursorPath() const = 0;

        /// \brief 获取默认光标路径
        ///
        /// \param cursorType 光标类型
        /// \return 光标图片路径
        virtual std::wstring GetDefaultCursorPath(CursorType cursorType) const = 0;

        /// \brief 移动光标位置
        ///
        /// \param worldPosition 光标位置
        virtual void MoveCursorToWorldPosition(const Vector3d& worldPosition) = 0;

        /// \brief 获取光标位置
        ///
        /// \param depth 深度
        /// \param worldPosition 输出参数，光标位置
        /// \return 光标在视图内返回true，否则返回false
        virtual bool GetCursorWorldPosition(float depth, Vector3d& worldPosition)const = 0;

        /// \brief 获取光标位置
        ///
        /// \return 光标所在位置
        virtual Vector3d GetCursorWorldPosition()const = 0;


        /// \brief 获取窗口的物理像素和与设备无关的像素之间的比率
        ///
        /// \return 窗口的物理像素和与设备无关的像素之间的比率
        virtual double GetDevicePixelRatio() const = 0;

        /// \brief 获取视图窗口宽度
        ///
        /// \return 视图窗口宽度
        virtual int GetWindowWidth() const = 0;

        /// \brief 设置视图宽度
        ///
        /// \param width 视图宽度
        virtual void SetWindowWidth(int width) = 0;

        /// \brief 获取视图窗口高度
        ///
        /// \return 视图窗口高度
        virtual int GetWindowHeight() const = 0;

        /// \brief 设置视图高度
        ///
        /// \param height 视图高度
        virtual void SetWindowHeight(int height) = 0;

        /// \brief 获取视图窗口位置（MDI区域左上角）
        ///
        /// \return 视图窗口位置
        virtual Vector2i GetWindowPosition() const = 0;

        /// \brief 设置视图位置（MDI区域左上角）
        ///
        /// \param x 左上点x坐标
        /// \param y 左上点y坐标
        virtual void SetWindowPosition(int x, int y) = 0;

        /// \brief 获取视图窗口标题
        ///
        /// \return 视图窗口标题
        virtual std::wstring GetTitle() const = 0;

        /// \brief 设置视图窗口标题
        ///
        /// \param windowTitle 视图窗口标题
        /// \return 设置成功返回true，否则返回false
        virtual bool SetTitle(const std::wstring& windowTitle) = 0;

        /// \brief 获取视图窗口的句柄
        ///
        /// \return 视图窗口的句柄
        virtual UInt64 GetUiViewId() const = 0;

        /// \brief 获取视图窗口是否最大化
        ///
        /// \return 视图窗口最大化状态返回true，否则返回false
        virtual bool IsMaximized() const = 0;

        /// \brief 获得视图上下文参数
        ///
        /// \return 视图上下文指针
        virtual OwnerPtr<IViewerContext> GetViewerContext() const = 0;

        /// \brief 获得视图鼠标事件
        ///
        /// \return 视图鼠标事件
        virtual IUiViewMouseEvent* GetUiViewMouseEvent() = 0;

        virtual bool IsValid() const = 0;

        /// \brief 刷新编辑框显示
        ///
        /// \return void
        virtual void RefreshEditModeBorder() = 0;

        /// \brief 是否在视图中启用拖放功能
        /// \param enable 是否开启
        virtual void EnableDraggingAwaySelectedElements(bool enable) = 0;

        /// \brief 视图中是否开启了拖放功能
        /// \return 是否开启
        virtual bool IsDraggingAwaySelectedElementsEnabled() const = 0;
    };

}   //namespace gcmp
